const Service = require('egg').Service;
const svgCaptcha = require('svg-captcha');

class AdminService extends Service {
    // 生成验证码
    async generateCaptcha() {
        const { ctx } = this;

        const captcha = svgCaptcha.create({
            size: 4, // 验证码长度
            ignoreChars: '0o1i', // 忽略容易混淆的字符
            noise: 2, // 干扰线条数
            color: true, // 彩色
            background: '#f0f2f5' // 背景色
        });

        // 将验证码文本存储到session中
        ctx.session.captcha = captcha.text.toLowerCase(); // 转为小写存储
        ctx.session.captchaId = Date.now().toString(); // 生成唯一ID

        // 设置session过期时间（5分钟）
        ctx.session.captchaExpire = Date.now() + 5 * 60 * 1000;

        return {
            captcha: captcha.data,
            captchaId: ctx.session.captchaId,
            expiresIn: 5 * 60 // 5分钟
        };
    }

    // 验证验证码
    async verifyCaptcha(captchaId, captchaText) {
        const { ctx } = this;

        // 检查session中是否存在验证码
        if (!ctx.session.captcha || !ctx.session.captchaId) {
            throw new Error('验证码已过期，请重新获取');
        }

        // 检查验证码ID是否匹配
        if (ctx.session.captchaId !== captchaId) {
            throw new Error('验证码ID不匹配');
        }

        // 检查验证码是否过期
        if (Date.now() > ctx.session.captchaExpire) {
            // 清除过期的验证码
            delete ctx.session.captcha;
            delete ctx.session.captchaId;
            delete ctx.session.captchaExpire;
            throw new Error('验证码已过期，请重新获取');
        }

        // 验证验证码文本（不区分大小写）
        if (ctx.session.captcha !== captchaText.toLowerCase()) {
            throw new Error('验证码错误');
        }

        // 验证成功后清除session中的验证码
        delete ctx.session.captcha;
        delete ctx.session.captchaId;
        delete ctx.session.captchaExpire;

        return true;
    }

    // 管理员登录 
    async login(loginData) {
        const { ctx } = this;

        const admin = await ctx.model.Admin.findOne({
            where: { email: loginData.email }
        });

        if (!admin) {
            throw new Error('管理员不存在');
        }

        if (admin.password !== loginData.password) {
            throw new Error('密码错误');
        }

        // 生成token
        const token = ctx.app.jwt.sign({
            admin_id: admin.admin_id,
            email: admin.email,
            type: 'admin' // 管理员类型
        }, ctx.app.config.jwt.secret, {
            expiresIn: ctx.app.config.jwt.expiresIn
        });

        const { createdAt, updatedAt, password, ...adminInfo } = admin.toJSON();
        return {
            admin: adminInfo,
            token
        };
    }

    // 创建管理员
    async create(adminData) {
        const { ctx } = this;

        // 检查邮箱是否已存在
        const existingAdmin = await ctx.model.Admin.findOne({
            where: { email: adminData.email }
        });
        if (existingAdmin) {
            throw new Error('邮箱已存在');
        }

        // 创建管理员
        const admin = await ctx.model.Admin.create({
            ...adminData,
            created_at: new Date(),
            updated_at: new Date(),
        });

        // 返回管理员信息（排除密码）
        const { createdAt, updatedAt, password, ...adminInfo } = admin.toJSON();
        return adminInfo;
    }

    // 获取管理员列表（分页）
    async getAdmins(query) {
        const { ctx } = this;
        const { page = 1, pageSize = 10, ...where } = query;

        const options = {
            where,
            limit: parseInt(pageSize),
            offset: (parseInt(page) - 1) * parseInt(pageSize),
            attributes: { exclude: ['password', 'createdAt', 'updatedAt'] },
            order: [['created_at', 'DESC']]
        };

        const { count, rows } = await ctx.model.Admin.findAndCountAll(options);

        return {
            list: rows,
            pagination: {
                page: parseInt(page),
                pageSize: parseInt(pageSize),
                total: count,
                totalPages: Math.ceil(count / pageSize)
            }
        };
    }

    // 根据ID获取管理员详情
    async getAdminById(adminId) {
        const { ctx } = this;

        const admin = await ctx.model.Admin.findByPk(adminId, {
            attributes: { exclude: ['password', 'createdAt', 'updatedAt'] }
        });

        if (!admin) {
            throw new Error('管理员不存在');
        }

        return admin;
    }

    // 更新管理员信息
    async updateAdmin(adminId, updateData) {
        const { ctx } = this;

        // 检查管理员是否存在
        const admin = await ctx.model.Admin.findByPk(adminId);
        if (!admin) {
            throw new Error('管理员不存在');
        }

        // 如果更新邮箱，检查是否重复
        if (updateData.email && updateData.email !== admin.email) {
            const existingAdmin = await ctx.model.Admin.findOne({
                where: { email: updateData.email }
            });
            if (existingAdmin) {
                throw new Error('邮箱已存在');
            }
        }

        // 更新管理员信息
        await admin.update({
            ...updateData,
            updated_at: new Date()
        });

        // 返回更新后的管理员信息（排除密码）
        const { createdAt, updatedAt, password, ...updatedAdmin } = admin.toJSON();
        return updatedAdmin;
    }

    // 删除管理员
    async deleteAdmin(adminId) {
        const { ctx } = this;

        const admin = await ctx.model.Admin.findByPk(adminId);
        if (!admin) {
            throw new Error('管理员不存在');
        }

        // 防止删除自己（根据业务需求）
        const token = ctx.request.header.token;
        if (token) {
            const decode = ctx.app.jwt.verify(token, ctx.app.config.jwt.secret);
            if (decode.admin_id === parseInt(adminId)) {
                throw new Error('不能删除自己');
            }
        }

        await admin.destroy();
        return true;
    }

    // 获取当前登录管理员信息
    async getCurrentAdmin(adminId) {
        const { ctx } = this;

        const admin = await ctx.model.Admin.findByPk(adminId, {
            attributes: { exclude: ['password', 'createdAt', 'updatedAt'] }
        });

        if (!admin) {
            throw new Error('管理员不存在');
        }

        return admin;
    }

    // 修改管理员密码
    async changePassword(adminId, passwordData) {
        const { ctx } = this;

        const admin = await ctx.model.Admin.findByPk(adminId);
        if (!admin) {
            throw new Error('管理员不存在');
        }

        // 验证旧密码
        if (admin.password !== passwordData.oldPassword) {
            throw new Error('原密码错误');
        }

        // 更新密码
        await admin.update({
            password: passwordData.newPassword,
            updated_at: new Date()
        });

        return true;
    }
    // 管理员登出
    async logout() {
        return true;
    }
}

module.exports = AdminService;